<template>
    <div class="merge-container">
        <!-- 固定在右上角的按钮组保持不变 -->
        <div class="fixed-action-buttons">
            <!-- 原有的直接混搭功能按钮 -->
            <el-button type="primary" @click="directVideoMixing" :loading="processing"
                :disabled="processing || matching">
                直接视频混搭
            </el-button>

            <!-- 修改单文件夹混搭按钮，点击打开对话框 -->
            <el-button type="warning" @click="startVideoMixingWithSelected(true)" :loading="processing"
                :disabled="processing || matching || !selectedVideos.length">
                单文件夹混搭
            </el-button>

            <el-button type="info" @click="matchVideosAction" :loading="matching" :disabled="processing || matching">
                预览匹配视频
            </el-button>

            <!-- 使用选中视频混搭按钮，只有在有选中视频时可用 -->
            <el-button type="success" :loading="processing" @click="openSingleFolderMixDialog"
                :disabled="processing || matching || !selectedVideos.length">
                使用选中视频混搭
            </el-button>

            <!-- 其他按钮保持不变 -->
            <el-button type="danger" @click="stopVideoMixing" :disabled="!processing">
                终止当前任务
            </el-button>

            <el-button @click="updateSearchData" :loading="updating" :disabled="updating || processing || matching">
                视频搜索数据更新
            </el-button>
        </div>
        <!-- 使用新的PromptInput组件 -->
        <PromptInput v-model="promptGroups" :categories="categories" :categories-loading="categoriesLoading" />

        <MatchedVideosPreview :video-groups="matchedVideos" :loading="matching"
            @update:selected-videos="handleSelectedVideosChange" />

        <!-- 音频组表格保持不变 -->
        <AudioGroupTable :audio-group="audioGroup" v-model:group-id="formData.group_id"
            @selection-change="handleSelectionChange" @add-audios="handleAddAudios" class="audio-group-section" />

        <el-card class="settings-card">
            <template #header>
                <div class="card-header">
                    <h2>混搭设置</h2>
                </div>
            </template>

            <el-form :model="formData" label-width="120px">
                <el-form-item label="每个分类匹配数量">
                    <el-input-number v-model="formData.randomLimit" :min="1" :max="10" />
                </el-form-item>

                <!-- 新增过渡特效选择 -->
                <TransitionEffectSelect v-model="formData.transitionEffect" />

                <el-form-item>
                    <el-checkbox v-model="formData.generateAll">生成所有组合</el-checkbox>
                    <el-checkbox v-model="formData.removeVoice" style="margin-left: 20px;">移除人声</el-checkbox>
                </el-form-item>

                <el-form-item label="日期时间筛选">
                    <el-date-picker v-model="dateRange" type="datetimerange" range-separator="至"
                        start-placeholder="开始日期" end-placeholder="结束日期" format="YYYY-MM-DD HH:mm:ss"
                        value-format="YYYY-MM-DD HH:mm:ss" style="width: 100%;" />
                </el-form-item>

                <el-form-item>
                    <el-button @click="clearDates" :disabled="processing">
                        清除日期
                    </el-button>
                </el-form-item>
            </el-form>
        </el-card>

        <log-console :logs="logs" @clear-logs="clearLogs" class="log-section" />

        <output-files-table :files="outputFiles" @refresh="refreshOutputFiles" class="output-files-card"
            :loading="processing" />

        <!-- 添加单文件夹混搭对话框 -->
        <single-folder-mix-dialog v-model:visible="singleFolderMixDialogVisible" :selected-videos="selectedVideos"
            @submit="handleSingleFolderMixSubmit" />
    </div>
</template>

<script>
import { ref, reactive, onMounted, onUnmounted, watch } from 'vue';
import { ElMessage, ElMessageBox } from 'element-plus';
import LogConsole from '@/components/LogConsole.vue';
import mergeService from '@/views/Mergeview/services/mergeService.js';
import FileSelector from '@/components/FileSelector.vue';
import settingsService from '@/services/settingsService.js';
import ResultPreview from '@/views/Mergeview/components/ResultPreview.vue';
import { useRoute, useRouter } from 'vue-router';
import OutputFilesTable from '@/views/Mergeview/components/OutputFilesTable.vue';
import AudioGroupTable from '@/views/Mergeview/components/AudioGroupTable.vue';
import PromptInput from '@/views/Mergeview/components/PromptInput.vue';
import MatchedVideosPreview from '@/views/Mergeview/MatchedVideosPreview.vue';
import SingleFolderMixDialog from '@/views/Mergeview/components/SingleFolderMixDialog.vue'; // 导入新组件
import TransitionEffectSelect from '@/components/TransitionEffectSelect.vue'

export default {
    name: 'MergeView',
    components: {
        LogConsole,
        FileSelector,
        ResultPreview,
        OutputFilesTable,
        AudioGroupTable,
        PromptInput,
        MatchedVideosPreview,
        SingleFolderMixDialog, // 注册新组件
        TransitionEffectSelect,
    },
    activated() {
        // 处理keep-alive激活事件
    },

    deactivated() {
        // 处理keep-alive失活事件
    },

    setup() {
        const processing = ref(false);
        const updating = ref(false);
        const logs = ref([]);

        // 新增状态变量
        const matching = ref(false); // 匹配视频中状态
        const matchedVideos = ref([]); // 匹配的视频列表
        const selectedVideos = ref([]); // 用户选中的视频
        const activeCollapse = ref(['prompts']); // 默认展开提示面板
        const matchDebounceTimer = ref(null);
        const shouldAutoMatch = ref(false);


        const statusInterval = ref(null);
        const route = useRoute();
        const router = useRouter();
        const categories = ref([]);
        const categoriesLoading = ref(false);
        const dateRange = ref([]);
        const showResults = ref(false);

        // 新增音频组相关变量
        const audioGroup = ref([]);
        const selectedAudioItems = ref([]);
        const audioTable = ref(null);

        const directVideoMixing = async () => {
            try {
                processing.value = true;

                // 准备日期范围
                const dateRangeObj = {};
                if (dateRange.value && dateRange.value.length === 2) {
                    dateRangeObj.start_date = dateRange.value[0];
                    dateRangeObj.end_date = dateRange.value[1];
                }

                // 准备提示数据
                const promptData = promptGroups.value
                    .filter(group => group.category)
                    .map((group, index) => [index + 1, group.category, group.text]);

                // 获取选中的音频文件ID列表
                const selectedAudioPaths = selectedAudioItems.value.map(item => item.id);

                // 设置处理参数
                const processingParams = {
                    generate_all: formData.generateAll,
                    remove_voice: formData.removeVoice,
                    transition_effect: formData.transitionEffect || undefined,
                };

                // 如果有选中音频项，则添加到audio_ids参数
                if (selectedAudioPaths.length > 0) {
                    processingParams.audio_ids = selectedAudioPaths;
                }

                const response = await mergeService.processMerge(
                    promptData,
                    formData.outputFolder,
                    processingParams,
                    dateRangeObj
                );

                if (response.success) {
                    ElMessage.success(response.message);
                    startStatusPolling();
                    saveSettings();
                    showResults.value = true;
                } else {
                    processing.value = false;
                    ElMessage.error(response.message || '启动失败');
                }
            } catch (error) {
                processing.value = false;
                ElMessage.error('启动失败: ' + error.message);
            }
        };

        // 2. 视频匹配操作 - 不自动开始混搭，只显示匹配结果
        const matchVideosAction = async () => {
            try {
                matching.value = true;
                matchedVideos.value = []; // 清空之前的结果

                // 准备日期范围
                const dateRangeObj = {};
                if (dateRange.value && dateRange.value.length === 2) {
                    dateRangeObj.start_date = dateRange.value[0];
                    dateRangeObj.end_date = dateRange.value[1];
                }

                // 准备提示数据
                const promptData = promptGroups.value
                    .filter(group => group.category)
                    .map((group, index) => {
                        // 计算总秒数
                        const totalSeconds = group.duration ?
                            (group.duration.minutes * 60 + group.duration.seconds) : 0;

                        // 返回带时长的提示数据
                        return [
                            index + 1,         // 序号
                            group.category,     // 分类
                            group.text,         // 提示词文本
                            totalSeconds > 0 ? totalSeconds : undefined  // 如果有设置时长，添加总秒数
                        ];
                    });

                // 设置搜索参数
                const searchParams = {
                    random_limit: formData.randomLimit,
                };

                // 调用匹配视频API
                const response = await mergeService.matchVideos(
                    promptData,
                    searchParams,
                    dateRangeObj
                );

                if (response.success && response.data) {
                    // 直接使用返回数据，添加关联提示词文本
                    matchedVideos.value = response.data.map(group => {
                        // 查找对应的原始提示词
                        const promptIndex = group.idx - 1;
                        const originalPrompt = promptGroups.value[promptIndex] || {};

                        // 添加提示词文本到数据结构
                        return {
                            ...group,
                            text: originalPrompt.text || '',
                            // 转换 data 字段为 videos 字段以兼容组件
                            videos: group.data.map(video => ({
                                id: video.video_id,
                                filename: video.description,
                                score: video.score,
                                username: video.username,
                                duration: video.duration,
                                // 估计其他必要字段
                                local_path: video.local_path || '',
                                created_at: video.download_at,
                                category: originalPrompt.category || '',
                                category_order: promptIndex + 1,
                            }))
                        };
                    }).filter(group => group.videos && group.videos.length > 0);

                    if (matchedVideos.value.length > 0) {
                        ElMessage.success(`成功匹配到${matchedVideos.value.length}个分类的视频`);
                        activeCollapse.value = [];
                    } else {
                        ElMessage.warning('没有找到匹配的视频');
                    }
                } else {
                    ElMessage.error(response.message || '匹配视频失败');
                }
            } catch (error) {
                ElMessage.error('匹配视频失败: ' + error.message);
            } finally {
                matching.value = false;
            }
        };

        // 3. 使用选中视频进行混搭
        const startVideoMixingWithSelected = async (no_folder = false, ext_data = {}) => {
            if (selectedVideos.value.length === 0) {
                ElMessage.warning('请先选择要混搭的视频');
                return;
            }

            try {
                processing.value = true;

                // 准备日期范围
                const dateRangeObj = {};
                if (dateRange.value && dateRange.value.length === 2) {
                    dateRangeObj.start_date = dateRange.value[0];
                    dateRangeObj.end_date = dateRange.value[1];
                }

                // 准备提示数据，保持与匹配时一致
                const promptData = promptGroups.value
                    .filter(group => group.category)
                    .map((group, index) => [index + 1, group.category, group.text]);

                // 获取选中的视频ID列表 - 注意这里需要使用正确的字段
                const selectedVideoIds = selectedVideos.value.map(video => ({
                    "id": video.id,
                    "category_order": video.category_order, // 添加顺序号
                    "category": video.category, // 添加分类字段
                })); // 这里使用id字段

                // 获取选中的音频文件ID列表
                const selectedAudioPaths = selectedAudioItems.value.map(item => item.id);

                // 设置处理参数
                const processingParams = {
                    no_folder: no_folder,
                    generate_all: formData.generateAll,
                    remove_voice: formData.removeVoice,
                    transition_effect: formData.transitionEffect || undefined,
                    video_ids: selectedVideoIds, // 传递选中的视频ID
                    ...ext_data,
                };

                // 如果有选中音频项，则添加到audio_ids参数
                if (selectedAudioPaths.length > 0) {
                    processingParams.audio_ids = selectedAudioPaths;
                }

                const response = await mergeService.processMergeByIds(
                    promptData,
                    formData.outputFolder,
                    processingParams,
                    dateRangeObj
                );

                if (response.success) {
                    ElMessage.success(response.message);
                    startStatusPolling();
                    saveSettings();
                    showResults.value = true;
                } else {
                    processing.value = false;
                    ElMessage.error(response.message || '启动失败');
                }
            } catch (error) {
                processing.value = false;
                ElMessage.error('启动失败: ' + error.message);
            }
        };

        // 处理选中视频变化
        const handleSelectedVideosChange = (videos) => {
            selectedVideos.value = videos;
        };

        // 初始化表单数据
        const formData = reactive({
            randomLimit: 3,
            generateAll: false,
            removeVoice: false,
            outputFolder: '',
            group_id: '',
            transitionEffect: '', // 新增过渡特效选择
        });

        // 初始化5个提示组
        // Replace the long initialization with:
        function createPromptGroups(count = 50) {
            return Array.from({ length: count }, () => ({
                category: '',
                text: '',
                duration: { minutes: 0, seconds: 0 }
            }));
        }
        const promptGroups = ref(createPromptGroups(50));

        // 加载分类列表
        const loadCategories = async () => {
            try {
                categoriesLoading.value = true;
                const response = await mergeService.getCategories();
                if (response.success && response.data) {
                    categories.value = response.data;
                } else {
                    ElMessage.warning('获取分类列表失败，使用默认分类');
                    // 使用默认分类作为备选
                }
            } catch (error) {
                console.error('加载分类失败:', error);
                ElMessage.error('加载分类失败');
                // 使用默认分类作为备选
            } finally {
                categoriesLoading.value = false;
            }
        };

        const ELMessageAler = (message, title = '提示', type = 'error') => {
            ElMessageBox.alert(message, title, {
                type: type,
                showClose: true,
            });
        };

        // 保存设置
        const saveSettings = () => {
            settingsService.saveSettings('merge_settings', {
                outputFolder: formData.outputFolder,
                randomLimit: formData.randomLimit,
                generateAll: formData.generateAll,
                removeVoice: formData.removeVoice,
                groupId: formData.group_id,
                transitionEffect: formData.transitionEffect, // 保存过渡特效选择
            });
        };

        // 其他功能方法保持不变
        const stopVideoMixing = async () => {
            try {
                const response = await mergeService.stopProcessing();

                if (response.success) {
                    ElMessage.success('已停止视频混搭任务');
                    processing.value = false;
                    stopStatusPolling();
                } else {
                    ElMessage.error(response.message || '停止任务失败');
                }
            } catch (error) {
                ElMessage.error('停止任务失败: ' + error.message);
            }
        };

        const handleAddAudios = (audios) => {
            // 确保audioGroup存在
            if (!audioGroup.value) {
                audioGroup.value = [];
            }

            // 过滤掉已存在的音频文件（根据file_path判断）
            const newAudios = audios.filter(audio =>
                !audioGroup.value.some(existingAudio => existingAudio.audio_path === audio.audio_path)
            );

            if (newAudios.length > 0) {
                // 给新添加的音频分配顺序号（从当前最大顺序号+1开始）
                const maxOrder = audioGroup.value.length > 0
                    ? Math.max(...audioGroup.value.map(item => item.order || 0))
                    : 0;

                newAudios.forEach((audio, index) => {
                    audio.order = maxOrder + index + 1;
                });

                // 添加到audioGroup中
                audioGroup.value = [...audioGroup.value, ...newAudios];
            }
        };

        // 添加视频结果相关变量
        const outputFiles = ref([]);
        const previewDialogVisible = ref(false);
        const selectedFile = ref(null);

        // 获取文件URL
        const getFileUrl = (file) => {
            if (!file || !file.output_path) return '';

            // 提取public之后的路径
            const pathParts = file.output_path.split('\\');
            const publicIndex = pathParts.findIndex(part => part === 'public');

            if (publicIndex !== -1) {
                // 构建URL路径
                const relativePath = pathParts.slice(publicIndex).join('/');
                return `${window.location.origin}/${relativePath}`;
            }

            // 如果没有找到public路径，使用原始路径但替换反斜杠
            return `${window.location.origin}/public/audios/${file.name}`;
        };

        // 预览文件
        const previewFile = (file) => {
            selectedFile.value = file;
            previewDialogVisible.value = true;
        };

        // 下载文件
        const downloadFile = (file) => {
            const url = getFileUrl(file);
            const a = document.createElement('a');
            a.href = url;
            a.download = file.name;
            document.body.appendChild(a);
            a.click();
            document.body.removeChild(a);
        };

        // 全选和取消全选功能
        const selectAll = () => {
            if (audioTable.value) {
                audioGroup.value.forEach(row => {
                    audioTable.value.toggleRowSelection(row, true);
                });
            }
        };

        const deselectAll = () => {
            if (audioTable.value) {
                audioTable.value.clearSelection();
            }
        };

        // 更新URL参数
        const updateUrlParams = () => {
            const query = { ...route.query };

            router.replace({ query });
        };

        // 监听group_id变化
        watch(
            () => formData.group_id,
            (newVal) => {
                updateUrlParams();
                if (newVal) {
                    loadAudioGroup(newVal);
                } else {
                    audioGroup.value = [];
                    selectedAudioItems.value = [];
                }
            },
        );

        // 加载音频组数据
        const loadAudioGroup = async (groupId) => {
            try {
                const response = await mergeService.getAudioGroup(groupId);
                if (response.success && response.data) {
                    // 对数据按order字段排序
                    audioGroup.value = response.data.sort((a, b) => a.order - b.order);
                } else {
                    ElMessage.error(response.message || '加载音频组失败');
                }
            } catch (error) {
                console.error('加载音频组失败:', error);
                ElMessage.error('加载音频组失败: ' + error.message);
            }
        };

        // 处理表格选择变化
        const handleSelectionChange = (selection) => {
            selectedAudioItems.value = selection;
        };

        // 获取meta_data中的文本内容
        const getMetaDataText = (metaDataStr) => {
            try {
                if (!metaDataStr) return '';
                // No need to parse since metaDataStr is already an object
                return metaDataStr.text || metaDataStr.name || '';
            } catch (e) {
                console.error('获取meta_data失败', e);
                return '';
            }
        };

        // 启动状态轮询
        const startStatusPolling = () => {
            stopStatusPolling(); // 确保先停止现有的轮询

            statusInterval.value = setInterval(async () => {
                try {
                    const response = await mergeService.getStatus();

                    // 检查是否有日志
                    if (response.logs && response.logs.length > 0) {
                        let lastLog = response.logs[(response.logs.length) - 1]
                        if (lastLog.level !== 'info') {
                            ElMessageBox.alert(lastLog.message, '报错信息', {
                                type: lastLog.level,
                                showClose: true,
                            });
                        }
                        logs.value = response.logs;
                    }

                    // 处理输出文件列表 - 直接替换而非追加
                    if (response.output_files && Array.isArray(response.output_files)) {
                        // 直接替换整个文件列表
                        outputFiles.value = response.output_files;
                    }

                    // 检查并处理错误信息
                    if (response.error) {
                        ElMessage.error(`处理错误: ${response.error}`);
                        processing.value = false;
                        stopStatusPolling();
                        return;
                    }

                    // 检查任务状态
                    if (response.status === 'error') {
                        const errorMsg = response.error_message || '视频混搭任务失败';
                        ElMessage.error(errorMsg);
                        processing.value = false;
                        stopStatusPolling();
                        return;
                    } else if (response.status === 'completed' && processing.value) {
                        processing.value = false;
                        stopStatusPolling();
                        ElMessage.success('视频混搭任务已完成');
                    }
                } catch (error) {
                    ElMessageBox.alert('获取状态失败，请稍后重试', '错误', {
                        type: 'error',
                        showClose: true,
                    });
                    ElMessage.error('获取状态失败: ' + (error.message || '未知错误'));
                    console.error('获取状态失败:', error);
                    // 对于网络错误等，不自动停止轮询，而是继续尝试
                }
            }, 2000);
        };

        // 停止状态轮询
        const stopStatusPolling = () => {
            if (statusInterval.value) {
                clearInterval(statusInterval.value);
                statusInterval.value = null;
            }
        };

        // 选择输出文件夹
        const selectOutputFolder = () => {
            ElMessage.info('在网页环境中，请直接输入目录路径');
        };

        // 更新refreshOutputFiles函数
        const refreshOutputFiles = async () => {
            try {
                const response = await mergeService.getStatus();

                // 检查并处理错误信息
                if (response.error) {
                    ElMessage.error(`刷新错误: ${response.error}`);
                    return;
                }

                if (response.output_files && Array.isArray(response.output_files)) {
                    outputFiles.value = response.output_files;
                }
            } catch (error) {
                console.error('获取输出文件失败:', error);
                ElMessage.error('获取输出文件失败: ' + (error.message || '未知错误'));
            }
        };

        // 清除日期
        const clearDates = () => {
            dateRange.value = [];
        };

        // 更新视频搜索数据
        const updateSearchData = async () => {
            try {
                updating.value = true;
                const response = await mergeService.updateSearchData();

                if (response.success) {
                    ElMessage.success('视频搜索数据更新已开始');

                    // 简单轮询更新状态
                    const checkUpdateStatus = setInterval(async () => {
                        const statusResponse = await mergeService.getStatus();
                        if (statusResponse.logs && statusResponse.logs.length > 0) {
                            logs.value = statusResponse.logs;
                        }

                        // 假设有某种方式来判断更新是否完成
                        if (statusResponse.status === 'completed') {
                            clearInterval(checkUpdateStatus);
                            updating.value = false;
                            ElMessage.success('视频搜索数据更新完成');
                        }
                    }, 2000);

                    // 设置超时，防止无限轮询
                    setTimeout(() => {
                        clearInterval(checkUpdateStatus);
                        if (updating.value) {
                            updating.value = false;
                        }
                    }, 60000); // 1分钟超时
                } else {
                    updating.value = false;
                    ElMessage.error(response.message || '更新失败');
                }
            } catch (error) {
                updating.value = false;
                ElMessage.error('更新失败: ' + error.message);
            } finally {
                updating.value = false;
            }
        };

        // 清空日志
        const clearLogs = () => {
            mergeService.clearLogs().then(() => {
                logs.value = [];
                ElMessage.success('日志已清空');
            }).catch(error => {
                console.error('清空日志失败:', error);
                ElMessage.error('清空日志失败: ' + error.message);
            });
        };

        // 组件挂载和卸载
        onMounted(() => {
            // 加载分类和过渡特效
            loadCategories();

            // 从URL中读取group_id参数
            if (route.query.group_id) {
                formData.group_id = route.query.group_id;
                loadAudioGroup(formData.group_id);
            }

            // 加载保存的设置
            const savedSettings = settingsService.loadSettings('merge_settings');
            if (savedSettings) {
                formData.outputFolder = savedSettings.outputFolder || '';
                formData.randomLimit = savedSettings.randomLimit || 3;
                formData.generateAll = savedSettings.generateAll !== undefined ?
                    savedSettings.generateAll : false;
                formData.removeVoice = savedSettings.removeVoice !== undefined ?
                    savedSettings.removeVoice : false;
                formData.transitionEffect = savedSettings.transitionEffect || '';

            }
        });

        onUnmounted(() => {
            stopStatusPolling();
            if (matchDebounceTimer.value) {
                clearTimeout(matchDebounceTimer.value);
            }
        });

        // 添加对话框状态变量
        const singleFolderMixDialogVisible = ref(false);

        // 添加打开对话框的方法
        const openSingleFolderMixDialog = () => {
            console.log('打开单文件夹混搭对话框');
            singleFolderMixDialogVisible.value = true;
            console.log('打开单文件夹混搭对话2框');
            if (selectedVideos.value.length === 0) {
                ElMessage.warning('请先选择要混搭的视频');
                return;
            }
        };

        // 添加对话框提交处理方法
        const handleSingleFolderMixSubmit = async (data) => {
            startVideoMixingWithSelected(false, data)
        };

        return {
            promptGroups,
            formData,
            dateRange,
            categories,
            categoriesLoading,
            logs,
            processing,
            updating,
            selectOutputFolder,
            clearDates,
            stopVideoMixing,
            updateSearchData,
            clearLogs,
            saveSettings,
            showResults,
            audioGroup,
            selectedAudioItems,
            handleSelectionChange,
            getMetaDataText,
            audioTable,
            selectAll,
            deselectAll,
            outputFiles,
            previewDialogVisible,
            selectedFile,
            previewFile,
            downloadFile,
            getFileUrl,
            refreshOutputFiles,
            handleAddAudios,
            matching,
            matchedVideos,
            selectedVideos,
            activeCollapse,
            matchVideosAction,
            handleSelectedVideosChange,
            matchDebounceTimer,
            shouldAutoMatch,
            directVideoMixing, // 新增方法
            matchVideosAction,
            startVideoMixingWithSelected, // 新增方法
            handleSelectedVideosChange,
            openSingleFolderMixDialog, // 新增方法
            handleSingleFolderMixSubmit, // 新增方法
            singleFolderMixDialogVisible, // 新增状态
        };
    }
};
</script>
<style scoped>
.merge-container {
    max-width: 1200px;
    margin: 0 auto;
    padding: 20px;
}

/* 添加固定按钮组样式 */
.fixed-action-buttons {
    position: fixed;
    top: 15px;
    right: 15px;
    z-index: 1000;
    display: flex;
    gap: 10px;
    background-color: rgba(255, 255, 255, 0.9);
    padding: 10px;
    border-radius: 4px;
    box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}

/* 在小屏幕上调整样式 */
@media screen and (max-width: 768px) {
    .fixed-action-buttons {
        flex-direction: column;
        right: 5px;
    }
}

.prompt-card,
.settings-card,
.audio-group-card {
    margin-bottom: 20px;
}

.card-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.header-actions {
    display: flex;
    align-items: center;
}

.selection-count {
    font-size: 14px;
    color: #606266;
    margin-right: 10px;
}

.prompt-groups {
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.prompt-group {
    display: flex;
    align-items: center;
}

.prompt-index {
    width: 25px;
    font-weight: bold;
}

.table-actions {
    margin-top: 15px;
    display: flex;
    gap: 10px;
}

.log-section {
    margin-top: 20px;
}

.result-section {
    margin-top: 20px;
}

.output-files-card {
    margin-top: 20px;
    margin-bottom: 20px;
}

.preview-container {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 15px;
}

.file-info {
    width: 100%;
    margin-top: 10px;
    padding: 10px;
    background-color: #f5f7fa;
    border-radius: 4px;
}

.file-info p {
    margin: 5px 0;
}

:deep(.el-card__header) {
    padding: 0 1em;
}

:deep(.el-card__header h2) {
    line-height: 1em;
    font-size: 16px;
}
</style>